package com.zxy.ziems.server.excel;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.zxy.btp.common.util.JsonUtils;
import com.zxy.ziems.common.pojo.modbus.DeviceConfigModbus;
import com.zxy.ziems.common.pojo.modbus.DevicePropertyConfigModbus;
import com.zxy.ziems.server.device.pojo.dto.*;
import com.zxy.ziems.server.device.pojo.entity.*;
import com.zxy.ziems.server.device.service.*;
import com.zxy.ziems.server.utils.AssertUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * @author 10348359
 * @create 2024-05-02 13:38
 */
@Slf4j
public class DeviceCollectorExcelListener implements ReadListener<DeviceCollectorExcelDTO> {


    /**
     * 调用
     *
     * @param data    数据
     * @param context 上下文
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invoke(DeviceCollectorExcelDTO data, AnalysisContext context) {
        log.info("读取到{}", JsonUtils.toJSONString(data));
        if (StrUtil.isBlank(data.getDeviceCode())) {
            log.error("[配置]没有设备编号，跳过");
            return;
        }
        String deviceType = data.getDeviceTypeCode();
        DeviceTypeEntity deviceTypeEntity = deviceTypeService.getByCode(data.getDeviceTypeCode());
        if (Objects.isNull(deviceTypeEntity)) {
            DeviceTypeDTO dto = new DeviceTypeDTO();
            dto.setCode(deviceType);
            dto.setName(deviceType);
            deviceTypeService.add(dto);
        }
        //先添加设备
        DeviceEntity deviceEntity = deviceService.getByCode(data.getDeviceCode(), data.getDeviceTypeCode());
        String deviceId;
        if (Objects.isNull(deviceEntity)) {
            DeviceDTO dto = new DeviceDTO();
            dto.setCode(data.getDeviceCode());
            dto.setName(data.getDeviceName());
            dto.setType(deviceType);
            deviceService.add(dto);
            deviceEntity = deviceService.getByCode(data.getDeviceCode(), data.getDeviceTypeCode());
            deviceId = deviceEntity.getId();
        } else {
            deviceId = deviceEntity.getId();
        }
        if (StrUtil.isBlank(data.getChannelName()) ||
            StrUtil.isBlank(data.getIp())) {
            log.error("[配置]没有通道名称和IP，跳过");
            return;
        }

        //创建通道
        ChannelEntity channelEntity = channelService.getByName(data.getChannelName());

        CollectorEntity collectorEntity = collectorService.getByCode(data.getCollectorCode());
        String collectorId;
        if (Objects.nonNull(collectorEntity)) {
            collectorId = collectorEntity.getId();
        } else {
            collectorId = null;
        }

        if (Objects.isNull(channelEntity)) {

            ChannelDTO dto = new ChannelDTO();
            dto.setName(data.getChannelName());
            String ip = data.getIp();
            List<String> ipList = StrUtil.split(ip, ":");
            if (ipList.size() < 2) {
                ipList = StrUtil.split(ip, "：");
            }
            dto.setIp(ipList.get(0));
            if (ipList.size() > 1) {
                dto.setPort(Integer.parseInt(ipList.get(1)));
            } else {
                dto.setPort(502);
            }
            dto.setDeviceTypeCode(deviceType);

            ProtocolEntity modbusTcp = protocolService.getByCode("ModbusTcp");
            dto.setProtocolId(modbusTcp.getId());
            dto.setCollectorId(collectorId);
            channelService.add(dto);

            channelEntity = channelService.getByName(data.getChannelName());
        }
        String channelId = channelEntity.getId();

        if (StrUtil.isBlank(data.getStation())) {
            log.error("[配置]没有从站地址，跳过");
            return;
        }
        //通道中添加设备
        ChannelDeviceEntity channelDeviceEntity = channelDeviceService.getByDeviceId(deviceEntity.getId());
        ChannelDeviceDTO<DeviceConfigModbus> channelDeviceDTO = new ChannelDeviceDTO<>();
        channelDeviceDTO.setDeviceId(deviceId);
        channelDeviceDTO.setChannelId(channelId);
        DeviceConfigModbus deviceConfigModbus = new DeviceConfigModbus();
        deviceConfigModbus.setStation(Integer.parseInt(data.getStation()));
        channelDeviceDTO.setAdvanced(deviceConfigModbus);
        if (Objects.isNull(channelDeviceEntity)) {
            channelDeviceService.add(channelDeviceDTO);
        } else {
            channelDeviceDTO.setId(channelDeviceEntity.getId());
            channelDeviceService.update(channelDeviceDTO);
        }

        //添加属性
        DataUnitEntity unitEntity = dataUnitService.getByCode(data.getUnitCode());
        DataUnitEntity dataUnitEntity = dataUnitService.getByCode(data.getDataUnitCode());
        AssertUtil.isFalse(Objects.isNull(unitEntity) || Objects.isNull(dataUnitEntity), "单位不存在");
        String unitId = unitEntity.getId();
        String dataUnitId = dataUnitEntity.getId();

        DataTypeEntity dataTypeEntity = dataTypeService.getByName(data.getPropertyName());
        AssertUtil.isFalse(Objects.isNull(dataTypeEntity), "数据属性不存在");
        String dataTypeId = dataTypeEntity.getId();
        //1 先给类型关联上属性
        DeviceTypePropertyEntity deviceTypePropertyEntity = deviceTypePropertyService.getByDevice(deviceTypeEntity.getCode(), dataTypeEntity.getId());
        if (Objects.isNull(deviceTypePropertyEntity)) {
            DeviceTypePropertyDTO dto = new DeviceTypePropertyDTO();
            dto.setName(dataTypeEntity.getName());
            dto.setDeviceTypeCode(deviceType);
            dto.setDataTypeId(dataTypeId);
            dto.setUnitId(unitId);
            deviceTypePropertyService.add(dto);
        }

        //2 再给具体设备配置属性及采集参数
        DevicePropertyEntity devicePropertyEntity = devicePropertyService.getBy(deviceEntity.getId(), dataTypeEntity.getId());
        DevicePropertyDTO<DevicePropertyConfigModbus> devicePropertyDTO = new DevicePropertyDTO<>();
        devicePropertyDTO.setName(dataTypeEntity.getName());
        devicePropertyDTO.setDeviceId(deviceId);
        devicePropertyDTO.setDataTypeId(dataTypeId);
        devicePropertyDTO.setUnitId(unitId);
        devicePropertyDTO.setDataUnitId(dataUnitId);
        devicePropertyDTO.setCollectInterval(10000);
        devicePropertyDTO.setNotifyType(0);
        DevicePropertyConfigModbus devicePropertyConfigModbus = new DevicePropertyConfigModbus();
        devicePropertyConfigModbus.setBitOffset(data.getBitOffset());
        devicePropertyConfigModbus.setType(data.getType());
        devicePropertyConfigModbus.setQuantity(data.getQuantity());
        devicePropertyConfigModbus.setByteOffset(data.getByteOffset());
        devicePropertyConfigModbus.setLittleEndian(!"是".equals(data.getBigEndian()));
        devicePropertyConfigModbus.setFunctionCode(data.getFunctionCode());
        devicePropertyConfigModbus.setStartAddress(data.getStartAddress());
        devicePropertyDTO.setAdvanced(devicePropertyConfigModbus);
        if (Objects.isNull(devicePropertyEntity)) {
            devicePropertyService.add(devicePropertyDTO);
        } else {
            devicePropertyDTO.setId(devicePropertyEntity.getId());
            devicePropertyDTO.setCollectInterval(devicePropertyEntity.getCollectInterval());
            devicePropertyDTO.setNotifyType(devicePropertyEntity.getNotifyType());
            devicePropertyService.update(devicePropertyDTO);
        }
    }


    /**
     * 毕竟做分析
     *
     * @param context 上下文
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
    }

    /**
     * 保存数据
     */
    private void saveData() {
    }

    public DeviceCollectorExcelListener() {
        devicePropertyService = SpringUtil.getBean(DevicePropertyService.class);
        deviceService = SpringUtil.getBean(DeviceService.class);
        deviceTypeService = SpringUtil.getBean(DeviceTypeService.class);
        devicePropertyService = SpringUtil.getBean(DevicePropertyService.class);
        deviceTypePropertyService = SpringUtil.getBean(DeviceTypePropertyService.class);

        dataTypeService = SpringUtil.getBean(DataTypeService.class);
        dataUnitService = SpringUtil.getBean(DataUnitService.class);
        protocolService = SpringUtil.getBean(ProtocolService.class);
        channelService = SpringUtil.getBean(ChannelService.class);
        collectorService = SpringUtil.getBean(CollectorService.class);
        channelDeviceService = SpringUtil.getBean(ChannelDeviceService.class);
    }

    private DeviceTypeService deviceTypeService;

    private DeviceService deviceService;

    private ChannelService channelService;

    private ChannelDeviceService channelDeviceService;

    private DeviceTypePropertyService deviceTypePropertyService;

    private DevicePropertyService devicePropertyService;

    private CollectorService collectorService;

    private ProtocolService protocolService;

    private DataUnitService dataUnitService;

    private DataTypeService dataTypeService;

}
